package com.yanqu.road.server.manager.tomb.event;

import com.yanqu.road.logic.activity.tomb.config.entity.ActivityTombFloor;
import com.yanqu.road.pb.tomb.Tomb;
import com.yanqu.road.server.manager.tomb.Position;
import com.yanqu.road.server.manager.tomb.TombMaze;
import com.yanqu.road.logic.activity.tomb.config.entity.ActivityTombEvent;
import com.yanqu.road.server.manager.tomb.entity.DbTombLog;
import com.yanqu.road.server.manager.tomb.entity.DbTombPosition;
import com.yanqu.road.server.manager.tomb.entity.DbTombUser;
import com.yanqu.road.server.manager.tomb.entity.PositionInfo;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.List;
import java.util.Random;

public class NpcBattle implements IEvent {

    @Override
    public boolean canStand(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        if (position.isDone()) {
            return true;
        }
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return true;
        }
        if (!dbTombPosition.isAlive()) {
            return true;
        }
        return false;
    }

    @Override
    public boolean canThrough(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        return canStand(dbTombUser, tombMaze, position);
    }

    @Override
    public boolean canExplore(DbTombUser dbTombUser, TombMaze tombMaze, Position position) {
        if (this.canStand(dbTombUser, tombMaze, position)) {
            return false;
        }
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return false;
        }

        return false;
    }

    @Override
    public void detail(TombMaze tombMaze, DbTombUser dbTombUser, Position position, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventExploreResp.Builder builder) {
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            return;
        }

        ActivityTombEvent activityTombEvent = tombMaze.getConfig().getEvent(dbTombPosition.getEventId());
        long digUser = dbTombPosition.acquireDigUser();
        DbTombUser digDbTombUser = tombMaze.getActivity().getDbData().getDbTombUser(digUser);
        positionTempBuilder.setEventConfig(activityTombEvent.getEventConfigBuilder());
        positionTempBuilder.setDigUser(digDbTombUser.toEventUserInfoBuilder());
        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setAttackTimes(dbTombPosition.getAttackTimes(dbTombUser.getUserId()));
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        positionTempBuilder.setOverTime(dbTombPosition.getCreateTime() + 10*1000);
    }

    @Override
    public void explore(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventExploreResp.Builder builder) {
        long maxHp = activityTombEvent.getParam2().get(2).get(0);

        long maxHp1 = tombMaze.getActivity().getDbData().getHpByRank(dbTombUser.getGroupId(), activityTombEvent.getParam2().get(0).get(0), activityTombEvent.getParam2().get(0).get(1));
        long maxHp2 = tombMaze.getActivity().getDbData().getHpByRatio(dbTombUser.getGroupId(), activityTombEvent.getParam2().get(1).get(0), activityTombEvent.getParam2().get(1).get(1));

        maxHp = Math.max(maxHp, maxHp1);
        maxHp = Math.max(maxHp, maxHp2);

        List<Integer> tomb_npc_hp_interval = tombMaze.getActivity().getConfig().getConfig().getTOMB_NPC_HP_INTERVAL();
        int p1 = tomb_npc_hp_interval.get(0);
        int p2 = tomb_npc_hp_interval.get(1);

        if (p2 > p1) {
            Random random = new Random();
            int i = random.nextInt(p2 - p1);
            int result = p1 + i;
            maxHp = (long) ((double) maxHp * (double) result / 1000);
        }


        ActivityTombFloor activityTombFloor = tombMaze.getActivity().getConfig().getFloor(tombMaze.getFloor());
        maxHp = (long) ((double) maxHp * (1 + (double) activityTombFloor.getMonsterHpAdd() / 1000));

        dbTombPosition.setMaxHp(maxHp);
        dbTombPosition.setCurrentHp(maxHp);

        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        positionTempBuilder.setOverTime(dbTombPosition.getCreateTime() + 10*1000);
    }

    public void display(DbTombUser dbTombUser, TombMaze tombMaze, Position position, Tomb.PositionTemp.Builder p) {
        DbTombPosition dbTombPosition = tombMaze.getDbTombPosition(position.getKey());
        if (dbTombPosition == null) {
            p.setIsOver(true);
            return;
        }
        if (!dbTombPosition.isAlive()) {
            p.setIsOver(true);
            return;
        }


        p.setMaxHp(dbTombPosition.getMaxHp());
        p.setHp(dbTombPosition.getCurrentHp());
        ActivityTombEvent event = tombMaze.getConfig().getEvent(dbTombPosition.getEventId());
        p.setEventConfig(event.getEventConfigBuilder());
        p.setIsOver(false);

    }

    @Override
    public void info(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventInfoResp.Builder builder) {

        long digUser = dbTombPosition.acquireDigUser();
        DbTombUser digDbTombUser = tombMaze.getActivity().getDbData().getDbTombUser(digUser);
        positionTempBuilder.setDigUser(digDbTombUser.toEventUserInfoBuilder());
        positionTempBuilder.setEventConfig(activityTombEvent.getEventConfigBuilder());
        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setAttackTimes(dbTombPosition.getAttackTimes(dbTombUser.getUserId()));
        String key = String.format("%d_%d_%d_%d", dbTombUser.getGroupId(), tombMaze.getFloor(), position.getRow(), position.getColumn());
        builder.addAllEventUserInfo(tombMaze.getEventUserInfoList(dbTombUser, key));
        positionTempBuilder.setOverTime(dbTombPosition.getCreateTime() + 10*1000);
    }

    @Override
    public void touch(TombMaze tombMaze, DbTombUser dbTombUser, DbTombPosition dbTombPosition, Position position, ActivityTombEvent activityTombEvent, Tomb.PositionTemp.Builder positionTempBuilder, Tomb.TombEventTouchResp.Builder builder, Tomb.TombEventTouchReq req) {

        if (dbTombUser.getUserId() != dbTombPosition.acquireDigUser()) {
            if (System.currentTimeMillis() < dbTombPosition.getCreateTime() + 10*1000){
                builder.setRet(GameErrorCode.E_TOMB_BATTLE_EVENT_PROTECT_TIME);
                return;
            }
        }

        boolean alive = dbTombPosition.isAlive();
        if (!alive) {
            builder.setRet(GameErrorCode.E_TOMB_TARGET_IS_NOT_ALIVE);
            return;
        }

        /**
         * 这里检查是否有足够的协助次数
         */
        if (dbTombPosition.acquireDigUser() != dbTombUser.getUserId()) {
            if (!tombMaze.checkIsEnoughAssistTimes(dbTombUser, 1)) {
                builder.setRet(GameErrorCode.E_TOMB_NOT_ENOUGH_ASSIST_TIMES);
                return;
            }
        }
        long costEnergy = 0;
        if (tombMaze.checkNeedCostEnergy(dbTombPosition, dbTombUser)) {
            List<Integer> tombEnergyCostSpecial = tombMaze.getActivity().getConfig().getConfig().getTOMB_ENERGY_COST_SPECIAL();
            int p1 = tombEnergyCostSpecial.get(0);
            int p2 = tombEnergyCostSpecial.get(1);
            ActivityTombFloor activityTombFloor = tombMaze.getActivity().getConfig().getFloor(tombMaze.getFloor());
            PositionInfo positionInfo = dbTombPosition.acquireEventInfo(dbTombUser.getUserId());

            long attackTimes = positionInfo.getAttackTimes();

            long e = activityTombFloor.getEnergy() + attackTimes * p1;
            e = Math.min(e, p2);
            costEnergy = e;
            boolean b = tombMaze.costEnergy(dbTombUser, (int) e, activityTombEvent.getId());
            if (!b) {
                builder.setRet(GameErrorCode.E_TOMB_USER_NOT_ENOUGH_ENERGY);
                return;
            }
            /**
             * 这里扣除协助次数
             */

            if (dbTombPosition.acquireDigUser() != dbTombUser.getUserId()) {
                if (!tombMaze.costAssistTimes(dbTombUser, 1)) {
                    builder.setRet(GameErrorCode.E_TOMB_NOT_ENOUGH_ASSIST_TIMES);
                    return;
                }
            }

        }

        long attack = dbTombUser.getTotalAttack();
        attack = dbTombPosition.underAttack(attack);

        Property property = null;
        if (attack > 0) {
            dbTombPosition.addEventInfo(dbTombUser.getUserId(), dbTombUser.getUserInfo().getNickName(), attack);
        }

        boolean isKilled = false;
        alive = dbTombPosition.isAlive();
        if (alive) {
            property = new Property();
        } else if (attack > 0) {
            isKilled = true;
            dbTombPosition.setFinishUserId(dbTombUser.getUserId());
            position.setKillUserId(dbTombUser.getUserId());


            property = new Property(activityTombEvent.getReward());
            Property randMonsterReward = activityTombEvent.randMonsterReward();
            property.addProperty(randMonsterReward);

            tombMaze.updateGrip(position);
            positionTempBuilder.setEventEnum(position.geteType());
            positionTempBuilder.setEnum(position.getpEnum());
            position.setpEnum(Tomb.PositionEnum.POSITION_EVENT_DONE_VALUE);
            tombMaze.eventDone(dbTombPosition, position);

//            tombMaze.refundUnAttackDigUserEnergy(dbTombPosition);
        }

        positionTempBuilder.setMaxHp(dbTombPosition.getMaxHp());
        positionTempBuilder.setHp(dbTombPosition.getCurrentHp());
        positionTempBuilder.setEnum(position.getpEnum());
        positionTempBuilder.setEventEnum(position.geteType());
        if (dbTombPosition.getFinishUserId() > 0) {
            DbTombUser dbTombUser1 = tombMaze.getActivity().getDbData().getDbTombUser(dbTombPosition.getFinishUserId());
            if (dbTombUser1 != null) {
                positionTempBuilder.setFinishUser(dbTombUser1.toEventUserInfoBuilder());
            }
        }
        if (attack > 0) {
            builder.setValue(attack);
            tombMaze.handleAttackScore(attack, dbTombPosition.getMaxHp(), activityTombEvent, property, dbTombUser);
            String key = String.format("%d_%d_%d_%d", dbTombUser.getGroupId(), tombMaze.getFloor(), position.getRow(), position.getColumn());
            tombMaze.eventBattleSyncPush(dbTombUser, attack, dbTombPosition.getCurrentHp(), key, false);
            dbTombPosition.refreshUpdateTime();
            position.refreshTimestamp();

            tombMaze.addProperty(property, dbTombUser);
            builder.setRewards(PropertyHelper.parsePropertyToString(property));

            //记日志
            if (isKilled) {
                //日志
                DbTombLog dbTombLog = DbTombLog.newInstance();
                dbTombLog.setUid(String.valueOf(dbTombUser.getUserId()));
                dbTombLog.setFloor(tombMaze.getFloor());
                dbTombLog.setFromUserId(dbTombUser.getUserId());
                dbTombLog.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                dbTombLog.setEventId(activityTombEvent.getId());
                dbTombLog.setValue(attack);
                dbTombLog.setValue1(activityTombEvent.getNpcId());
                dbTombLog.setRewards(builder.getRewards());
                dbTombLog.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                dbTombLog.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                dbTombLog.setX(position.getRow());
                dbTombLog.setY(position.getColumn());
                dbTombLog.setDescription("杀死普通守卫");
                dbTombLog.setGroupId(dbTombUser.getGroupId());
                dbTombLog.setStatus(1);
                tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog, false);

                tombMaze.getDbTombMaze().addEventDone(activityTombEvent.getId());

                if (activityTombEvent.isBigEvent()) {

                    //日志
                    DbTombLog dbTombLog2 = DbTombLog.newInstance();
                    dbTombLog2.setUid(String.valueOf(tombMaze.getActivityId()));
                    dbTombLog2.setFloor(tombMaze.getFloor());
                    dbTombLog2.setFromUserId(dbTombUser.getUserId());
                    dbTombLog2.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                    dbTombLog2.setEventId(activityTombEvent.getId());
                    dbTombLog2.setValue(attack);
                    dbTombLog2.setValue1(activityTombEvent.getNpcId());
                    dbTombLog2.setRewards(builder.getRewards());
                    dbTombLog2.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                    dbTombLog2.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                    dbTombLog2.setX(position.getRow());
                    dbTombLog2.setY(position.getColumn());
                    dbTombLog2.setGroupId(dbTombUser.getGroupId());
                    dbTombLog2.setDescription("杀死普通守卫");
                    dbTombLog2.setStatus(1);
                    tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog2, true);

                    tombMaze.npcInfoPush();
                }

            } else {
                if (activityTombEvent.isBigEvent()) {
                    //日志
                    DbTombLog dbTombLog = DbTombLog.newInstance();
                    dbTombLog.setUid(String.valueOf(dbTombUser.getUserId()));
                    dbTombLog.setFloor(tombMaze.getFloor());
                    dbTombLog.setFromUserId(dbTombUser.getUserId());
                    dbTombLog.setLogEnum(Tomb.TombLogEnum.TombLogEnum_Battle_VALUE);
                    dbTombLog.setEventId(activityTombEvent.getId());
                    dbTombLog.setValue(attack);
                    dbTombLog.setValue1(activityTombEvent.getNpcId());
                    dbTombLog.setRewards(builder.getRewards());
                    dbTombLog.setEnergyChange(-activityTombEvent.getConsumeEnergy());
                    dbTombLog.setEnergy(dbTombUser.getEnergy(tombMaze.getConfig().getConfig()));
                    dbTombLog.setX(position.getRow());
                    dbTombLog.setY(position.getColumn());
                    dbTombLog.setGroupId(dbTombUser.getGroupId());
                    dbTombLog.setDescription("攻击普通守卫");
                    tombMaze.getActivity().getTombLog().addDbTombLog(dbTombLog, false);
                }

            }

            //发到游戏服写日志
            Tomb.TombLogCrossToGameReq.Builder logBuilder = Tomb.TombLogCrossToGameReq.newBuilder();
            logBuilder.setLEnum(Tomb.GameTombLogEnum.BATTLE);
            logBuilder.setUserId(dbTombUser.getUserId());
            logBuilder.setActivityId(tombMaze.getActivityId());
            logBuilder.setUnionUid(dbTombUser.getUserInfo().getUnionUid());
            logBuilder.setFloor(dbTombUser.getFloor());
            logBuilder.setX(position.getRow());
            logBuilder.setY(position.getColumn());
            logBuilder.setHp(dbTombUser.getHp());
            logBuilder.setTimestamp(System.currentTimeMillis());
            Tomb.TombLogBattle.Builder battle = Tomb.TombLogBattle.newBuilder();
            battle.setIsPvp(0);
            battle.setAttack(attack);
            battle.setBattleId(activityTombEvent.getNpcId());
            battle.setRivalMaxHp(dbTombPosition.getMaxHp());
            battle.setRivalHp(dbTombPosition.getCurrentHp());
            battle.setCostEnergy(costEnergy);
            if (isKilled) {
                battle.setIsKill(1);
            } else {
                battle.setIsKill(0);
            }
            logBuilder.setBattle(battle);
            Tomb.TombLogMove.Builder logMoveBuilder = Tomb.TombLogMove.newBuilder();
            logMoveBuilder.setEventId(dbTombPosition.getEventId());
            logBuilder.setMove(logMoveBuilder);
            tombMaze.getActivity().sendLogToGame(dbTombUser, logBuilder);
        }

    }
}
